package controller

import (
	"Short_chain_cats/database"
	"Short_chain_cats/user/model"
	"Short_chain_cats/user/service"
	"Short_chain_cats/util"
	"os"
	"time"

	"github.com/gin-gonic/gin"
)

type userController struct {
	*Controller
	*service.UserService
}

var UserController = userController{
	Controller:  BaseController,
	UserService: service.NewUserService(),
}

// Create 注册新用户
func (r userController) Create(ctx *gin.Context) {
	var param model.CreateUserCommand
	// 使用 c.ShouldBind 来绑定请求数据并进行验证
	if err := ctx.ShouldBindJSON(&param); err != nil {
		util.RespFailed(ctx, util.ParamError, util.Translate(err))
		return
	}
	if user, err := r.UserService.Create(ctx, &param); err != nil {
		util.RespFailed(ctx, util.Failed, err.Error())
		return
	} else {
		// 增加 Redis 中的注册人数计数
		key := "user:count"
		database.RedisClient.Incr(ctx, key).Result()
		//database.RedisClient.Incr(ctx, "registered_user_count")
		// 注册曲线的存储 注册成功后增加当天的计数器
		today := time.Now().Format("2006-01-02")
		//todayKey := fmt.Sprintf("user:register:count:%s", today)
		//_, err = database.RedisClient.Incr(ctx, todayKey).Result()
		//if err != nil {
		//	util.RespFailed(ctx, util.Failed, err.Error())
		//	return
		//}
		// 将当天的注册人数存储在 Redis Map 中
		_, err = database.RedisClient.HIncrBy(ctx, "user:register:daily", today, 1).Result()
		if err != nil {
			util.RespFailed(ctx, util.Failed, err.Error())
			return
		}
		// 如果是第一次设置当天的键，设置过期时间
		//if _, err = database.RedisClient.TTL(ctx, todayKey).Result(); err == nil {
		//	database.RedisClient.Expire(ctx, todayKey, 24*time.Hour) // 过期时间设置为1天
		//}
		// 设置 Redis Map 的过期时间为两周
		database.RedisClient.Expire(ctx, "user:register:daily", 14*24*time.Hour) // 过期时间设置为2周
		util.RespSuccess(ctx, "用户注册成功", user)
	}
}

// Login 用户登录
func (r userController) Login(ctx *gin.Context) {
	var param model.UserLoginCommand
	// 使用 ctx.ShouldBindJSON 来绑定请求数据并进行验证
	if err := ctx.ShouldBindJSON(&param); err != nil {
		util.RespFailed(ctx, util.ParamError, util.Translate(err))
		return
	}
	if user, err := r.UserService.Login(ctx, &param); err != nil {
		util.RespFailed(ctx, util.Failed, err.Error())
		return
	} else {
		util.RespSuccess(ctx, "用户登录成功", user)
	}
}

// RefreshToken 刷新逻辑
func (r userController) RefreshToken(ctx *gin.Context) {
	var param model.RefreshTokenCommand
	// 使用 ctx.ShouldBindJSON 来绑定请求数据并进行验证
	if err := ctx.ShouldBindJSON(&param); err != nil {
		util.RespFailed(ctx, util.ParamError, util.Translate(err))
		return
	}
	newAccessToken, err := r.UserService.RefreshToken(ctx, param.UserAccount)
	if err != nil {
		util.RespFailed(ctx, util.Failed, err.Error())
		return
	}
	util.RespSuccess(ctx, "token刷新成功，data里面是最新的aToken", newAccessToken)
}

func (r userController) UploadPicture(ctx *gin.Context) {
	// 处理上传的图片
	avatar, err := ctx.FormFile("file")
	if err != nil {
		util.RespFailed(ctx, util.ParamError, util.Translate(err))
		return
	}
	url, uploadErr := util.UploadPic(avatar.Filename, avatar)
	if uploadErr != nil {
		util.RespFailed(ctx, util.ParamError, util.Translate(uploadErr))
		return
	}
	if err = r.UserService.UploadPicture(ctx, url); err != nil {
		util.RespFailed(ctx, util.Failed, err.Error())
		return
	}
	util.RespSuccess(ctx, "头像上传成功，data里面是avatar的url", url)
}

func (r userController) SendEmailCode(ctx *gin.Context) {
	var param model.EmailCommand
	// 使用 ctx.ShouldBindJSON 来绑定请求数据并进行验证
	if err := ctx.ShouldBindJSON(&param); err != nil {
		util.RespFailed(ctx, util.ParamError, util.Translate(err))
		return
	}

	if err := r.UserService.SendEmailCode(ctx, &param); err != nil {
		util.RespFailed(ctx, util.Failed, err.Error())
		return
	} else {
		util.RespSuccess(ctx, "验证码已发送，请在5分钟能填写验证码", nil)
	}

}

// UpdateUserInfo 修改用户信息
func (r userController) UpdateUserInfo(ctx *gin.Context) {
	var param model.UpdateUserCommand
	// 使用 ctx.ShouldBindJSON 来绑定请求数据并进行验证
	if err := ctx.ShouldBindJSON(&param); err != nil {
		util.RespFailed(ctx, util.ParamError, util.Translate(err))
		return
	}
	if user, err := r.UserService.UpdateUserInfo(ctx, &param); err != nil {
		util.RespFailed(ctx, util.Failed, err.Error())
		return
	} else {
		util.RespSuccess(ctx, "用户信息修改成功", user)
	}
}

// ForgetPassword 忘记密码
func (r userController) ForgetPassword(ctx *gin.Context) {
	var param model.ForgetPasswordCommand
	// 使用 ctx.ShouldBindJSON 来绑定请求数据并进行验证
	if err := ctx.ShouldBindJSON(&param); err != nil {
		util.RespFailed(ctx, util.ParamError, util.Translate(err))
		return
	}
	if user, err := r.UserService.ForgetPassword(ctx, &param); err != nil {
		util.RespFailed(ctx, util.Failed, err.Error())
		return
	} else {
		util.RespSuccess(ctx, "用户密码修改成功", user)
	}
}

// UpdateUserPassword 修改用户密码
func (r userController) UpdateUserPassword(ctx *gin.Context) {
	var param model.UpdateUserPasswordCommand
	// 使用 ctx.ShouldBindJSON 来绑定请求数据并进行验证
	if err := ctx.ShouldBindJSON(&param); err != nil {
		util.RespFailed(ctx, util.ParamError, util.Translate(err))
		return
	}
	if user, err := r.UserService.UpdateUserPassword(ctx, &param); err != nil {
		util.RespFailed(ctx, util.Failed, err.Error())
		return
	} else {
		util.RespSuccess(ctx, "用户密码修改成功", user)
	}
}

func (r userController) UserCount(ctx *gin.Context) {
	userCount, err := r.UserService.GetRegisteredUserCount(ctx)
	if err != nil {
		util.RespFailed(ctx, util.Failed, err.Error())
		return
	} else {
		//util.RespSuccess(ctx, "用户注册人数查询成功，data里面是userCount值", fmt.Sprintf("userCount:%d", userCount))
		util.RespSuccess(ctx, "用户注册人数查询成功，data里面是userCount值", userCount)
	}
}

func (r userController) ShortChainCount(ctx *gin.Context) {
	if shortChainCount, err := r.UserService.ShortChainCount(ctx); err != nil {
		util.RespFailed(ctx, util.Failed, err.Error())
		return
	} else {
		//util.RespSuccess(ctx, "短链生成数量查询成功", fmt.Sprintf("shortChainCount:%d", shortChainCount))
		util.RespSuccess(ctx, "短链生成数量查询成功，data里面是shortChainCount值", shortChainCount)
	}
}

func (r userController) GetDailyRegisterCounts(ctx *gin.Context) {
	var param model.DateCommand
	// 使用 ctx.ShouldBindJSON 来绑定请求数据并进行验证
	if err := ctx.ShouldBindJSON(&param); err != nil {
		if err.Error() != "EOF" {
			util.RespFailed(ctx, util.ParamError, util.Translate(err))
			return
		}
	}
	// 如果StartDate为空，设置默认值为两周前的日期
	if param.StartDate == "" {
		param.StartDate = time.Now().AddDate(0, 0, -14).Format("2006-01-02")
	}

	// 如果EndDate为空，设置默认值为今天的日期
	if param.EndDate == "" {
		param.EndDate = time.Now().Format("2006-01-02")
	}

	if result, err := r.UserService.GetDailyRegisterCounts(ctx, param.StartDate, param.EndDate); err != nil {
		util.RespFailed(ctx, util.Failed, err.Error())
		return
	} else {
		util.RespSuccess(ctx, "用户注册人数变化查询成功", result)
	}
}

func (r userController) ShortChainGenerate(ctx *gin.Context) {
	var param model.DateCommand
	// 使用 ctx.ShouldBindJSON 来绑定请求数据并进行验证
	if err := ctx.ShouldBindJSON(&param); err != nil {
		if err.Error() != "EOF" {
			util.RespFailed(ctx, util.ParamError, util.Translate(err))
			return
		}
	}
	// 如果StartDate为空，设置默认值为两周前的日期
	if param.StartDate == "" {
		param.StartDate = time.Now().AddDate(0, 0, -14).Format("2006-01-02")
	}

	// 如果EndDate为空，设置默认值为今天的日期
	if param.EndDate == "" {
		param.EndDate = time.Now().Format("2006-01-02")
	}
	if result, err := r.UserService.GetDailyShortChainCounts(ctx, param.StartDate, param.EndDate); err != nil {
		util.RespFailed(ctx, util.Failed, err.Error())
		return
	} else {
		util.RespSuccess(ctx, "短链生成数量变化查询成功", result)
	}
}

func (r userController) GetUserList(ctx *gin.Context) {
	var param model.GetALLCommand
	// 使用 ctx.ShouldBindJSON 来绑定请求数据并进行验证
	if err := ctx.ShouldBindJSON(&param); err != nil {
		util.RespFailed(ctx, util.ParamError, util.Translate(err))
		return
	}
	r.ParsePage(param.Page, param.PageSize)
	articles, totalCount, err := r.UserService.GetAll(ctx, param.UserAccount, param.UserProfile, param.UserRole, r.Page, r.PageSize, param.CreateOrder, param.UpdateOrder)
	if err != nil {
		util.RespFailed(ctx, util.Failed, err.Error())
	} else {
		util.RespSuccess(ctx, "用户列表查询成功", Pagination{
			List:       articles,
			Page:       r.Page,
			PageSize:   r.PageSize,
			TotalCount: totalCount,
		})
	}
	return
}

func (r userController) EditUser(ctx *gin.Context) {
	var param model.EditUserCommand
	// 使用 ctx.ShouldBindJSON 来绑定请求数据并进行验证
	if err := ctx.ShouldBindJSON(&param); err != nil {
		util.RespFailed(ctx, util.ParamError, util.Translate(err))
		return
	}
	if user, err := r.UserService.EditUserInfo(ctx, &param); err != nil {
		util.RespFailed(ctx, util.Failed, err.Error())
		return
	} else {
		util.RespSuccess(ctx, "用户信息修改成功", user)
	}
}

func (r userController) DeleteUser(ctx *gin.Context) {
	var param model.IdCommand
	// 使用 ctx.ShouldBindJSON 来绑定请求数据并进行验证
	if err := ctx.ShouldBindJSON(&param); err != nil {
		util.RespFailed(ctx, util.ParamError, util.Translate(err))
		return
	}
	if err := r.UserService.DeleteUsers(ctx, param.Id); err != nil {
		util.RespFailed(ctx, util.Failed, err.Error())
		return
	} else {
		util.RespSuccess(ctx, "删除成功", nil)
	}
}

func (r userController) ExportExcel(ctx *gin.Context) {
	//file, _, err := ctx.Request.FormFile("file")
	//if err != nil {
	//	util.RespFailed(ctx, util.Failed, util.Translate(err))
	//	return
	//}
	var param model.ExportExcelCommand
	// 使用 ctx.ShouldBindJSON 来绑定请求数据并进行验证
	if err := ctx.ShouldBindJSON(&param); err != nil {
		util.RespFailed(ctx, util.ParamError, util.Translate(err))
		return
	}
	filePath, err := r.UserService.ExportExcel(param.User)
	if err != nil {
		util.RespFailed(ctx, util.Failed, util.Translate(err))
		return
	}
	// 设置响应头,告诉浏览器这是一个文件下载请求
	ctx.Header("Content-Disposition", "attachment; filename=users.xlsx")
	ctx.Header("Content-Type", "application/octet-stream")

	// 将文件内容写入响应体
	ctx.File(filePath)

	// 删除临时文件
	os.Remove(filePath)
	util.RespSuccess(ctx, "导出成功", nil)
}
